{
 "cells": [
  {
   "cell_type": "code",
   "execution_count": 1,
   "id": "7e128cb9",
   "metadata": {},
   "outputs": [],
   "source": [
    "# pytorch\n",
    "import torch\n",
    "import torch.nn as nn\n",
    "# Mobile Net\n",
    "# from MobileNetV2 import mobilenet_v2\n",
    "from MobileNetV3_qat import mobilenetv3_large, mobilenetv3_small"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 7,
   "id": "5958ed51",
   "metadata": {},
   "outputs": [
    {
     "ename": "AssertionError",
     "evalue": "did not find fuser method for: (<class 'torch.nn.modules.container.Sequential'>,) ",
     "output_type": "error",
     "traceback": [
      "\u001b[0;31m---------------------------------------------------------------------------\u001b[0m",
      "\u001b[0;31mAssertionError\u001b[0m                            Traceback (most recent call last)",
      "Cell \u001b[0;32mIn[7], line 5\u001b[0m\n\u001b[1;32m      3\u001b[0m model\u001b[38;5;241m.\u001b[39mqconfig \u001b[38;5;241m=\u001b[39m torch\u001b[38;5;241m.\u001b[39mao\u001b[38;5;241m.\u001b[39mquantization\u001b[38;5;241m.\u001b[39mget_default_qat_qconfig(\u001b[38;5;124m'\u001b[39m\u001b[38;5;124mx86\u001b[39m\u001b[38;5;124m'\u001b[39m)\n\u001b[1;32m      4\u001b[0m fuse_list \u001b[38;5;241m=\u001b[39m [[\u001b[38;5;124m'\u001b[39m\u001b[38;5;124mconv\u001b[39m\u001b[38;5;124m'\u001b[39m]]\n\u001b[0;32m----> 5\u001b[0m model_fp32_fused \u001b[38;5;241m=\u001b[39m \u001b[43mtorch\u001b[49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43mao\u001b[49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43mquantization\u001b[49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43mfuse_modules\u001b[49m\u001b[43m(\u001b[49m\u001b[43mmodel\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[43mfuse_list\u001b[49m\u001b[43m)\u001b[49m\n\u001b[1;32m      6\u001b[0m model\n",
      "File \u001b[0;32m/data/lambd4/anaconda3/py39/lib/python3.9/site-packages/torch/ao/quantization/fuse_modules.py:158\u001b[0m, in \u001b[0;36mfuse_modules\u001b[0;34m(model, modules_to_fuse, inplace, fuser_func, fuse_custom_config_dict)\u001b[0m\n\u001b[1;32m    103\u001b[0m \u001b[38;5;28;01mdef\u001b[39;00m \u001b[38;5;21mfuse_modules\u001b[39m(model, modules_to_fuse, inplace\u001b[38;5;241m=\u001b[39m\u001b[38;5;28;01mFalse\u001b[39;00m, fuser_func\u001b[38;5;241m=\u001b[39mfuse_known_modules, fuse_custom_config_dict\u001b[38;5;241m=\u001b[39m\u001b[38;5;28;01mNone\u001b[39;00m):\n\u001b[1;32m    104\u001b[0m \u001b[38;5;250m    \u001b[39m\u001b[38;5;124mr\u001b[39m\u001b[38;5;124;03m\"\"\"Fuses a list of modules into a single module\u001b[39;00m\n\u001b[1;32m    105\u001b[0m \n\u001b[1;32m    106\u001b[0m \u001b[38;5;124;03m    Fuses only the following sequence of modules:\u001b[39;00m\n\u001b[0;32m   (...)\u001b[0m\n\u001b[1;32m    156\u001b[0m \n\u001b[1;32m    157\u001b[0m \u001b[38;5;124;03m    \"\"\"\u001b[39;00m\n\u001b[0;32m--> 158\u001b[0m     \u001b[38;5;28;01mreturn\u001b[39;00m \u001b[43m_fuse_modules\u001b[49m\u001b[43m(\u001b[49m\n\u001b[1;32m    159\u001b[0m \u001b[43m        \u001b[49m\u001b[43mmodel\u001b[49m\u001b[43m,\u001b[49m\n\u001b[1;32m    160\u001b[0m \u001b[43m        \u001b[49m\u001b[43mmodules_to_fuse\u001b[49m\u001b[43m,\u001b[49m\n\u001b[1;32m    161\u001b[0m \u001b[43m        \u001b[49m\u001b[43mis_qat\u001b[49m\u001b[38;5;241;43m=\u001b[39;49m\u001b[38;5;28;43;01mFalse\u001b[39;49;00m\u001b[43m,\u001b[49m\n\u001b[1;32m    162\u001b[0m \u001b[43m        \u001b[49m\u001b[43minplace\u001b[49m\u001b[38;5;241;43m=\u001b[39;49m\u001b[43minplace\u001b[49m\u001b[43m,\u001b[49m\n\u001b[1;32m    163\u001b[0m \u001b[43m        \u001b[49m\u001b[43mfuser_func\u001b[49m\u001b[38;5;241;43m=\u001b[39;49m\u001b[43mfuser_func\u001b[49m\u001b[43m,\u001b[49m\n\u001b[1;32m    164\u001b[0m \u001b[43m        \u001b[49m\u001b[43mfuse_custom_config_dict\u001b[49m\u001b[38;5;241;43m=\u001b[39;49m\u001b[43mfuse_custom_config_dict\u001b[49m\u001b[43m)\u001b[49m\n",
      "File \u001b[0;32m/data/lambd4/anaconda3/py39/lib/python3.9/site-packages/torch/ao/quantization/fuse_modules.py:100\u001b[0m, in \u001b[0;36m_fuse_modules\u001b[0;34m(model, modules_to_fuse, is_qat, inplace, fuser_func, fuse_custom_config_dict)\u001b[0m\n\u001b[1;32m     97\u001b[0m \u001b[38;5;28;01melse\u001b[39;00m:\n\u001b[1;32m     98\u001b[0m     \u001b[38;5;66;03m# Handle case of modules_to_fuse being a list of lists\u001b[39;00m\n\u001b[1;32m     99\u001b[0m     \u001b[38;5;28;01mfor\u001b[39;00m module_list \u001b[38;5;129;01min\u001b[39;00m modules_to_fuse:\n\u001b[0;32m--> 100\u001b[0m         \u001b[43m_fuse_modules_helper\u001b[49m\u001b[43m(\u001b[49m\u001b[43mmodel\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[43mmodule_list\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[43mis_qat\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[43mfuser_func\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[43mfuse_custom_config_dict\u001b[49m\u001b[43m)\u001b[49m\n\u001b[1;32m    101\u001b[0m \u001b[38;5;28;01mreturn\u001b[39;00m model\n",
      "File \u001b[0;32m/data/lambd4/anaconda3/py39/lib/python3.9/site-packages/torch/ao/quantization/fuse_modules.py:84\u001b[0m, in \u001b[0;36m_fuse_modules_helper\u001b[0;34m(model, modules_to_fuse, is_qat, fuser_func, fuse_custom_config_dict)\u001b[0m\n\u001b[1;32m     81\u001b[0m     mod_list\u001b[38;5;241m.\u001b[39mappend(_get_module(model, item))\n\u001b[1;32m     83\u001b[0m \u001b[38;5;66;03m# Fuse list of modules\u001b[39;00m\n\u001b[0;32m---> 84\u001b[0m new_mod_list \u001b[38;5;241m=\u001b[39m \u001b[43mfuser_func\u001b[49m\u001b[43m(\u001b[49m\u001b[43mmod_list\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[43mis_qat\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[43madditional_fuser_method_mapping\u001b[49m\u001b[43m)\u001b[49m\n\u001b[1;32m     86\u001b[0m \u001b[38;5;66;03m# Replace original module list with fused module list\u001b[39;00m\n\u001b[1;32m     87\u001b[0m \u001b[38;5;28;01mfor\u001b[39;00m i, item \u001b[38;5;129;01min\u001b[39;00m \u001b[38;5;28menumerate\u001b[39m(modules_to_fuse):\n",
      "File \u001b[0;32m/data/lambd4/anaconda3/py39/lib/python3.9/site-packages/torch/ao/quantization/fuse_modules.py:52\u001b[0m, in \u001b[0;36mfuse_known_modules\u001b[0;34m(mod_list, is_qat, additional_fuser_method_mapping)\u001b[0m\n\u001b[1;32m     39\u001b[0m \u001b[38;5;250m\u001b[39m\u001b[38;5;124mr\u001b[39m\u001b[38;5;124;03m\"\"\"Returns a list of modules that fuses the operations specified\u001b[39;00m\n\u001b[1;32m     40\u001b[0m \u001b[38;5;124;03m in the input module list.\u001b[39;00m\n\u001b[1;32m     41\u001b[0m \n\u001b[0;32m   (...)\u001b[0m\n\u001b[1;32m     49\u001b[0m \u001b[38;5;124;03mthe fused operation. The rest of the elements are set to nn.Identity()\u001b[39;00m\n\u001b[1;32m     50\u001b[0m \u001b[38;5;124;03m\"\"\"\u001b[39;00m\n\u001b[1;32m     51\u001b[0m types \u001b[38;5;241m=\u001b[39m \u001b[38;5;28mtuple\u001b[39m(type_before_parametrizations(m) \u001b[38;5;28;01mfor\u001b[39;00m m \u001b[38;5;129;01min\u001b[39;00m mod_list)\n\u001b[0;32m---> 52\u001b[0m fuser_method \u001b[38;5;241m=\u001b[39m \u001b[43mget_fuser_method\u001b[49m\u001b[43m(\u001b[49m\u001b[43mtypes\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[43madditional_fuser_method_mapping\u001b[49m\u001b[43m)\u001b[49m\n\u001b[1;32m     53\u001b[0m \u001b[38;5;28;01mif\u001b[39;00m fuser_method \u001b[38;5;129;01mis\u001b[39;00m \u001b[38;5;28;01mNone\u001b[39;00m:\n\u001b[1;32m     54\u001b[0m     \u001b[38;5;28;01mraise\u001b[39;00m \u001b[38;5;167;01mNotImplementedError\u001b[39;00m(\u001b[38;5;124mf\u001b[39m\u001b[38;5;124m\"\u001b[39m\u001b[38;5;124mCannot fuse modules: \u001b[39m\u001b[38;5;132;01m{\u001b[39;00mtypes\u001b[38;5;132;01m}\u001b[39;00m\u001b[38;5;124m\"\u001b[39m)\n",
      "File \u001b[0;32m/data/lambd4/anaconda3/py39/lib/python3.9/site-packages/torch/ao/quantization/fuser_method_mappings.py:190\u001b[0m, in \u001b[0;36mget_fuser_method\u001b[0;34m(op_list, additional_fuser_method_mapping)\u001b[0m\n\u001b[1;32m    187\u001b[0m all_mappings \u001b[38;5;241m=\u001b[39m get_combined_dict(_DEFAULT_OP_LIST_TO_FUSER_METHOD,\n\u001b[1;32m    188\u001b[0m                                  additional_fuser_method_mapping)\n\u001b[1;32m    189\u001b[0m fuser_method \u001b[38;5;241m=\u001b[39m all_mappings\u001b[38;5;241m.\u001b[39mget(op_list, \u001b[38;5;28;01mNone\u001b[39;00m)\n\u001b[0;32m--> 190\u001b[0m \u001b[38;5;28;01massert\u001b[39;00m fuser_method \u001b[38;5;129;01mis\u001b[39;00m \u001b[38;5;129;01mnot\u001b[39;00m \u001b[38;5;28;01mNone\u001b[39;00m, \u001b[38;5;124mf\u001b[39m\u001b[38;5;124m\"\u001b[39m\u001b[38;5;124mdid not find fuser method for: \u001b[39m\u001b[38;5;132;01m{\u001b[39;00mop_list\u001b[38;5;132;01m}\u001b[39;00m\u001b[38;5;124m \u001b[39m\u001b[38;5;124m\"\u001b[39m\n\u001b[1;32m    191\u001b[0m \u001b[38;5;28;01mreturn\u001b[39;00m fuser_method\n",
      "\u001b[0;31mAssertionError\u001b[0m: did not find fuser method for: (<class 'torch.nn.modules.container.Sequential'>,) "
     ]
    }
   ],
   "source": [
    "model = mobilenetv3_small()\n",
    "model.eval()\n",
    "model.qconfig = torch.ao.quantization.get_default_qat_qconfig('x86')\n",
    "fuse_list = [['conv']]\n",
    "model_fp32_fused = torch.ao.quantization.fuse_modules(model, fuse_list)\n",
    "model"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "b38af1f7",
   "metadata": {},
   "outputs": [],
   "source": []
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3 (ipykernel)",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.9.19"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 5
}
